import { Provide } from '@midwayjs/core';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository, In } from 'typeorm';
import { CheckDataEntity } from '../entity/checkData';
import { OrderInfoEntity } from '../../order/entity/info';
import { StudentStudentEntity } from '../entity/student';
import { ProductProductEntity } from '../../product/entity/product';
import { ClassTrainLogEntity } from '../../class/entity/trainLog';
import { DictInfoEntity } from '../../dict/entity/info';

/**
 * 处方服务
 */
@Provide()
export class StudentCheckDataService extends BaseService {
  @InjectEntityModel(CheckDataEntity)
  checkDataEntity: Repository<CheckDataEntity>;

  @InjectEntityModel(OrderInfoEntity)
  orderInfoEntity: Repository<OrderInfoEntity>;

  @InjectEntityModel(StudentStudentEntity)
  studentStudentEntity: Repository<StudentStudentEntity>;

  @InjectEntityModel(ProductProductEntity)
  productProductEntity: Repository<ProductProductEntity>;

  @InjectEntityModel(ClassTrainLogEntity)
  classTrainLogEntity: Repository<ClassTrainLogEntity>;

  @InjectEntityModel(DictInfoEntity)
  dictInfoEntity: Repository<DictInfoEntity>;

  // 重写page方法，当isExport存在，size设置为9999
  async page(query: any, options: any) {
    if (query.isExport) {
      options.size = 9999;
    }
    const result = await super.page(query, options);
    // 初始化数据
    result.list.forEach((item) => {
      item.totalPrice = 0;
      item.productName = '';
      item.student = null;
      item.trainCount = 0;
      item.inGroup = '';
      item.layer = '';
      // 将时间戳checkInterval转为天数，并且取整
      item.checkInterval = Math.round(Number(item.checkInterval) / 1000 / 60 / 60 / 24);
    });
    // 获取字典数据
    const dict = await this.dictInfoEntity.find();
    // 查询学员已支付订单的总额，并且拼接上
    const studentIds = result.list.map((item) => item.studentId);
    const order = await this.orderInfoEntity.find({
      where: {
        userId: In(studentIds),
        status: 1,
      },
    });
    // 将数组ProductIds合并为一个数组
    const productIds = order.reduce((pre, cur) => {
      return pre.concat(cur.ProductIds);
    }, []);
    const product = await this.productProductEntity.find({
      where: {
        id: In(productIds),
      },
    });
    // console.log('productIds', productIds);
    // 查询所有学员对象
    const students = await this.studentStudentEntity.find({
      where: {
        id: In(studentIds),
      },
    });
    // 查询参加的视训次数
    const train = await this.classTrainLogEntity.find({
      where: {
        studentId: In(studentIds),
      },
    });
    result.list.forEach((item) => {
      const student = students.find((pre) => {
        return pre.id === item.studentId;
      });
      const trainCount = train.filter((pre) => {
        return pre.studentId === item.studentId;
      }).length;
      if (student) {
        item.student = student;
        item.trainCount = trainCount;
        if (student.inGroup) {
            item.inGroup = dict.find((pre) => {
            return pre.id === student.inGroup;
          }).name;
        }
        if (student.layer) {
          item.layer = dict.find((pre) => {
            return pre.id === student.layer;
          }).name;
        }
      }
    });

    // console.log(studentIds, order);
    // 计算学员已支付订单的总额
    order.forEach((item) => {
      const preData = result.list.find((pre) => {
        return pre.studentId === item.userId;
      });
      // console.log('preData', preData);
      if (preData) {
        // 将item.payAmount转为数值
        preData.totalPrice += Number(item.payAmount);
        // 拼接上商品名称
        item.ProductIds.forEach((id) => {
          const productName = product.find((pre) => {
            return pre.id === id;
          }).name;
          preData.productName += productName + ',';
        });
        // 去掉最后一个逗号
        preData.productName = preData.productName.slice(0, -1);
      }
    });


    return result;
  }

  // 左右眼数据合并为一个数据
  async mergeEyeData() {
    const checkData = await this.checkDataEntity.find();
    // 如果学员id和检查次数一致，则保留bodyPart=0的数据，并且把bodyPar=1的数据中上升下降的数值和检查数据合并到bodyPart=0的数据中
    checkData.forEach((item) => {
      if (item.bodyPart === 1) {
        const preData = checkData.find((pre) => {
          return pre.studentId === item.studentId && pre.checkTimes === item.checkTimes && pre.bodyPart == 0;
        });
        if (preData) {
          preData.bodyPart2 = item.bodyPart;
          preData.checkData2 = item.checkData;
          preData.riseOrFall2 = item.riseOrFall;
          preData.riseOrFallValue2 = item.riseOrFallValue;
        }
      }
    });
    // 合并完成后，删除bodyPart=1的数据
    checkData.forEach((item) => {
      if (item.bodyPart === 1) {
        this.checkDataEntity.delete(item.id);
      }
    });
    // 合并完成后，更新bodyPart=0的数据
    checkData.forEach((item) => {
      if (item.bodyPart === 0) {
        this.checkDataEntity.update(item.id, {
          bodyPart2: item.bodyPart2,
          checkData2: item.checkData2,
          riseOrFall2: item.riseOrFall2,
          riseOrFallValue2: item.riseOrFallValue2,
        });
      }
    });
  }


  // 清洗眼轴数据
  async cleanEyeAxisData() {
    // 对所有眼轴数据进行学员id分组，然后每个检查日期再分为一组，根据日期的先后，往后每次检查都会递增一次检查次数checkTimes
    const checkData = await this.checkDataEntity.find({
      order: {
        checkTime: 'ASC',
      }
    });
    // 对眼轴数据进行学员id分类和日期分类，日期需要是升序排列
    const checkDataMap = checkData.reduce((pre, cur) => {
      if (!pre[cur.studentId]) {
        pre[cur.studentId] = {};
      }
      if (!pre[cur.studentId][cur.checkTime]) {
        pre[cur.studentId][cur.checkTime] = [];
      }
      pre[cur.studentId][cur.checkTime].push(cur);
      return pre;
    }, {});
    // 对日期数组里面的对象进行计数更新，例如日期1组里面的对象都是为1，2组里面的对象都是为2
    // 需要对每次日期里面检查部位bodyPart一致的检查数据跟前一次数据进行升降对比，如果数值上升则上升riseOrFall=1，下降则下降riseOrFall=2
    for (const studentId in checkDataMap) {
      const studentCheckData = checkDataMap[studentId];
      let checkTimes = 1;
      let tempData = {};
      let preCheckTime = 0;
      for (const checkTime in studentCheckData) {
        const checkDataList = studentCheckData[checkTime];

        // 如果一天中有多次检查数据，则只保留检查时间是最后一次的检查数据
        // 根据checkTime去分类，同一天的放到一起
        let preId = 0;
        checkDataList.forEach((checkData) => {
          checkData.checkTimes = checkTimes;
          if (checkTimes === 1) {
            checkData.checkInterval = 0;
          } else {
            // 转为时间戳再相减
            const preCheckTimeTS = new Date(preCheckTime).getTime();
            const curCheckTimeTS = new Date(checkData.checkTime).getTime();
            checkData.checkInterval = curCheckTimeTS - preCheckTimeTS;
            // 如果相隔时间小于1天则删除之前的，并且次数等于前一个的次数
            if (checkData.checkInterval < 24 * 60 * 60 * 1000 && preId != 0) {
              checkData.checkTimes = checkTimes - 1;
              this.checkDataEntity.delete(preId);
            }
            preId = checkData.id;
            console.log('checkData', checkData.checkInterval, curCheckTimeTS, preCheckTimeTS);
          }
          
          preCheckTime = checkData.checkTime;
          // 对检查部位进行分组
          // if (!tempData[checkData.bodyPart]) {
          //   tempData[checkData.bodyPart] = checkData.checkData;
          // } else {
          //   // 对检查部位数据进行升降对比，并且将正负的数值保存到riseOrFallValue
          //   const preCheckData = tempData[checkData.bodyPart];
          //   if (checkData.checkData > preCheckData) {
          //     checkData.riseOrFall = 1;
          //     checkData.riseOrFallValue = checkData.checkData - preCheckData;
          //   } else if (checkData.checkData < preCheckData) {
          //     checkData.riseOrFall = 2;
          //     checkData.riseOrFallValue = checkData.checkData - preCheckData;
          //   } else {
          //     checkData.riseOrFall = 0;
          //     checkData.riseOrFallValue = 0;
          //     // 如果checkTimes不是1，说明不是第一次检查，视为不变
          //     if (checkTimes !== 1) {
          //       checkData.riseOrFall = 4; // 不变
          //     }
          //   }
          //   tempData[checkData.bodyPart] = checkData.checkData;
          // }
        });
        checkTimes++;
      }
    }

    
    // 对眼轴数据进行保存
    for (const studentId in checkDataMap) {
      const studentCheckData = checkDataMap[studentId];
      for (const checkTime in studentCheckData) {
        const checkDataList = studentCheckData[checkTime];
        await this.checkDataEntity.save(checkDataList);
      }
    }
  }
}
